package com.zkthink.ceres.file.controller;


import static com.zkthink.exception.code.ExceptionCode.BASE_VALID_PARAM;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zkthink.base.R;
import com.zkthink.base.controller.DeleteController;
import com.zkthink.base.controller.QueryController;
import com.zkthink.base.controller.SuperSimpleController;
import com.zkthink.base.request.PageParams;
import com.zkthink.ceres.file.dto.AttachmentDTO;
import com.zkthink.ceres.file.dto.AttachmentResultDTO;
import com.zkthink.ceres.file.dto.AttachmentUpdateDTO;
import com.zkthink.ceres.file.dto.FilePageReqDTO;
import com.zkthink.ceres.file.entity.Attachment;
import com.zkthink.ceres.file.service.AttachmentService;
import com.zkthink.context.BaseContextHandler;
import com.zkthink.log.annotation.SysLog;
import com.zkthink.utils.BizAssert;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

/**
 * <p>
 * 素材表 前端控制器
 * </p>
 *
 * @author ceres
 * @since 2019-04-29
 */
@RestController
@RequestMapping("/attachment")
@Slf4j
@Api(value = "素材管理", tags = "素材管理")
@Validated
@SysLog(enabled = false)
public class AttachmentController extends SuperSimpleController<AttachmentService, Attachment>
    implements QueryController<Attachment, Long, FilePageReqDTO>,
    DeleteController<Attachment, Long> {


  @Override
  public void query(PageParams<FilePageReqDTO> params, IPage<Attachment> page, Long defSize) {
    baseService.page(page, params.getModel());
  }

  @Override
  public R<Boolean> handlerDelete(List<Long> ids) {
    return R.success(baseService.remove(ids));
  }


  @PostMapping("/updateAttachmentTag")
  @ApiOperation(value = "更新素材标签", notes = "更新素材标签")
  public R updateAttachmentTag(@RequestBody @Validated AttachmentUpdateDTO attachmentUpdateDTO) {
    Attachment attachment = new Attachment().setTagId(attachmentUpdateDTO.getTagId());
    attachment.setId(attachmentUpdateDTO.getAttachmentId());
    baseService.updateById(attachment);
    return R.success();
  }


  /**
   * 上传文件
   *
   * @author ceres
   * @date 2019-05-06 16:28
   */
  @ApiOperation(value = "素材上传", notes = "素材上传")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "id", value = "文件id", dataType = "long", paramType = "query"),
      @ApiImplicitParam(name = "tagId", value = "标签id", dataType = "long", paramType = "query"),
      @ApiImplicitParam(name = "file", value = "文件", dataType = "MultipartFile", allowMultiple = true, required = true),
  })
  @PostMapping(value = "/upload")
  @SysLog("上传素材")
  public R<AttachmentDTO> upload(
      @RequestParam(value = "file") MultipartFile file,
      @RequestParam(value = "id", required = false) Long id,
      @RequestParam(value = "tagId", required = false) Long tagId) {
    // 忽略路径字段,只处理文件类型
    if (file.isEmpty()) {
      return R.fail(BASE_VALID_PARAM.build("请求中必须至少包含一个有效文件"));
    }
    String tenant = BaseContextHandler.getTenant();

    AttachmentDTO attachment = baseService.upload(file, tenant, id, tagId);

    return R.success(attachment);
  }


  @ApiOperation(value = "查询素材", notes = "查询素材")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "tagId", value = "标签id", dataType = "long", paramType = "query"),
      @ApiImplicitParam(name = "dataType", value = "文件类型,图片：IMAGE  视频：VIDEO", dataType = "string", paramType = "query")
  })
  @ApiResponses(
      @ApiResponse(code = 60103, message = "文件id为空")
  )
  @GetMapping
  @SysLog("根据业务类型查询素材")
  public R<List<AttachmentResultDTO>> findAttachment(
      @RequestParam(value = "tagId", required = true) Long tagId,
      @RequestParam(value = "dataType", required = true) String dataType) {
    return R.success(baseService.find(tagId, dataType));
  }


  /**
   * 下载一个文件或多个文件打包下载
   *
   * @param ids 文件id
   */
  @ApiOperation(value = "根据文件id打包下载", notes = "根据素材id下载多个打包的素材")
  @GetMapping(value = "/download", produces = "application/octet-stream")
  @SysLog("下载素材")
  public void download(
      @ApiParam(name = "ids[]", value = "文件id 数组")
      @RequestParam(value = "ids[]") Long[] ids,
      HttpServletRequest request, HttpServletResponse response) throws Exception {
    BizAssert.isTrue(ArrayUtils.isNotEmpty(ids), BASE_VALID_PARAM.build("素材id不能为空"));
    baseService.download(request, response, ids);
  }


  /**
   * 根据下载地址下载文件
   *
   * @param url 文件链接
   * @param filename 文件名称
   * @author ceres
   * @date 2019-05-12 21:24
   */
  @ApiOperation(value = "根据url下载文件(不推荐)", notes = "根据文件的url下载文件(不推荐使用，若要根据url下载，请执行通过nginx)")
  @ApiImplicitParams({
      @ApiImplicitParam(name = "url", value = "文件url", dataType = "string", paramType = "query"),
      @ApiImplicitParam(name = "filename", value = "文件名", dataType = "string", paramType = "query"),
  })
  @GetMapping(value = "/download/url", produces = "application/octet-stream")
  @SysLog("根据文件连接下载文件")
  public void downloadUrl(@RequestParam(value = "url") String url,
      @RequestParam(value = "filename", required = false) String filename,
      HttpServletRequest request, HttpServletResponse response) throws Exception {
    BizAssert.isTrue(StringUtils.isNotEmpty(url), BASE_VALID_PARAM.build("素材下载地址不能为空"));
    log.info("name={}, url={}", filename, url);
    baseService.downloadByUrl(request, response, url, filename);
  }

}
